import { toast } from "@/hooks/use-toast"

// Generate random file names
const fileNames = [
  "项目文档.pdf",
  "设计稿.psd",
  "会议记录.docx",
  "预算表.xlsx",
  "产品介绍.pptx",
  "合同文件.pdf",
  "照片_2024.jpg",
  "视频素材.mp4",
  "音频文件.mp3",
  "代码备份.zip",
  "年度报告.pdf",
  "客户资料.xlsx",
  "营销方案.docx",
  "UI设计.fig",
  "数据分析.xlsx",
]

const folderNames = ["工作文件", "个人文档", "项目资料", "照片", "视频", "音乐", "下载"]

const mimeTypes = {
  pdf: "application/pdf",
  docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
  jpg: "image/jpeg",
  png: "image/png",
  mp4: "video/mp4",
  mp3: "audio/mpeg",
  zip: "application/zip",
  txt: "text/plain",
  psd: "application/x-photoshop",
  fig: "application/x-figma",
}

function getRandomSize() {
  return Math.floor(Math.random() * 50000000) + 1000
}

function getRandomDate() {
  const now = Date.now()
  const daysAgo = Math.floor(Math.random() * 30)
  return new Date(now - daysAgo * 24 * 60 * 60 * 1000).toISOString()
}

function getMimeType(fileName: string) {
  const ext = fileName.split(".").pop()?.toLowerCase()
  return (mimeTypes[ext as keyof typeof mimeTypes] || "application/octet-stream") as string
}

type ApiResponse<T> = {
  code: number
  data: T
  msg?: string
}

function isApiResponse<T>(value: unknown): value is ApiResponse<T> {
  return (
    typeof value === "object" &&
    value !== null &&
    "code" in value &&
    typeof (value as { code: unknown }).code === "number"
  )
}

function unwrapMockResponse<T>(value: T | ApiResponse<T>): T {
  if (isApiResponse<T>(value)) {
    if (value.code === 1) {
      return value.data
    }
    throw new Error(value.msg || "接口返回错误")
  }
  return value
}

// Generate mock files
function generateMockFiles(count = 10, includeFolder = true) {
  const files = []

  // Add some folders
  if (includeFolder) {
    const folderCount = Math.floor(Math.random() * 3) + 1
    for (let i = 0; i < folderCount; i++) {
      files.push({
        id: Math.floor(Math.random() * 1000000),
        fileName: folderNames[i % folderNames.length] + (i > 0 ? ` ${i + 1}` : ""),
        isDirectory: true,
        createdTime: getRandomDate(),
      })
    }
  }

  // Add files
  for (let i = 0; i < count - files.length; i++) {
    const fileName = fileNames[Math.floor(Math.random() * fileNames.length)]
    files.push({
      id: Math.floor(Math.random() * 1000000),
      fileName,
      isDirectory: false,
      fileSize: getRandomSize(),
      mimeType: getMimeType(fileName),
      createdTime: getRandomDate(),
    })
  }

  return files
}

// Check if response is JSON
async function isJsonResponse(response: Response): Promise<boolean> {
  const contentType = response.headers.get("content-type")
  if (contentType?.includes("application/json")) {
    return true
  }
  return false
}

// Wrapper for API calls with mock fallback
export async function apiCall<T>(
  url: string,
  options?: RequestInit,
  mockData?: T,
  mockGenerator?: () => T | ApiResponse<T>,
): Promise<T> {
  const requestOptions: RequestInit = { ...(options ?? {}) }
  const token = typeof window !== "undefined" ? localStorage.getItem("driveJWTToken") : null
  const headers = new Headers(requestOptions.headers)

  if (token && !headers.has("Authorization")) {
    headers.set("Authorization", `Bearer ${token}`)
  }

  requestOptions.headers = headers

  try {
    const response = await fetch(url, requestOptions)

    if (response.status === 401) {
      throw new Error("Unauthorized", { cause: response })
    }

    // Check if response is JSON
    const isJson = await isJsonResponse(response)

    if (!isJson) {
      // Not JSON response means API is not implemented, use mock data
      toast({
        title: "使用模拟数据",
        description: `后端接口 ${requestOptions.method ?? "GET"} ${url} 未实现/响应不对，正在使用模拟数据进行演示`,
        variant: "warning",
        duration: 5000,
      })

      if (mockGenerator) {
        const mockResponse = await Promise.resolve(mockGenerator())
        return unwrapMockResponse(mockResponse)
      }

      if (mockData) {
        return mockData
      }

      throw new Error("No mock data available")
    }

    if (response.ok) {
      const res = await response.json()
      if (res.code === 1) {
        return res.data
      }
      throw new Error(res.msg, { cause: res.code || res, })
    }

    throw new Error(`API call failed: ${response.status}`)
  } catch (error) {
    // Network error or API not available, use mock data
    console.log("[v0] API call failed, using mock data:", error)

    if (error instanceof Error && error.cause) {
      throw error
    }

    toast({
      title: "使用模拟数据",
      description: `后端接口 ${requestOptions.method ?? "GET"} ${url} 未实现/响应不对，正在使用模拟数据进行演示`,
      variant: "warning",
      duration: 5000,
    })

    if (mockGenerator) {
      const mockResponse = await Promise.resolve(mockGenerator())
      return unwrapMockResponse(mockResponse)
    }

    if (mockData) {
      return mockData
    }

    throw error
  }
}

// Mock data generators
export const mockGenerators = {
  login: (): ApiResponse<string> => ({
    code: 1,
    data: "mock-jwt-token-" + Math.random().toString(36).substring(7),
    msg: "",
  }),

  currentUser: (): ApiResponse<{
    id: number
    username: string
    email?: string
  }> => ({
    code: 1,
    data: {
      id: 1,
      username: "demo-user",
      email: "demo@example.com",
    },
    msg: "",
  }),

  register: (): ApiResponse<string> => ({
    code: 1,
    data: "mock-jwt-token-" + Math.random().toString(36).substring(7),
    msg: "注册成功",
  }),

  files: (): ApiResponse<
    Array<{
      id: number
      fileName: string
      isDirectory: boolean
      fileSize?: number
      mimeType?: string
      createdTime: string
    }>
  > => ({
    code: 1,
    data: generateMockFiles(12),
    msg: "",
  }),

  search: (keyword: string): ApiResponse<
    Array<{
      id: number
      fileName: string
      isDirectory: boolean
      fileSize?: number
      mimeType?: string
      createdTime: string
      snippet: string
    }>
  > => {
    const files = generateMockFiles(5, false).map((file) => {
      const fileName = file.fileName.includes(keyword) ? file.fileName : `搜索结果-${file.fileName}`
      return {
        ...file,
        fileName,
        snippet: `包含关键词「${keyword}」的文件`,
      }
    })

    return {
      code: 1,
      data: files,
      msg: "",
    }
  },

  share: (): ApiResponse<{
    id: string
  }> => ({
    code: 1,
    data: {
      id: Math.random().toString(36).substring(7),
    },
    msg: "",
  }),

  sharedFile: (): ApiResponse<{
    file: {
      id: number
      fileName: string
      fileSize: number
      mimeType: string
      createdTime: string
      isDirectory: boolean
    }
    expireTime?: string
  }> => ({
    code: 1,
    data: {
      file: {
        id: Math.floor(Math.random() * 1000000),
        fileName: "共享文件.pdf",
        fileSize: getRandomSize(),
        mimeType: "application/pdf",
        createdTime: getRandomDate(),
        isDirectory: false,
      },
      expireTime: Math.random() > 0.5 ? new Date(Date.now() + 3 * 24 * 60 * 60 * 1000).toISOString() : undefined,
    },
    msg: "",
  }),

  storage: (): ApiResponse<{
    used: number
    total: number
  }> => ({
    code: 1,
    data: {
      used: 5.2 * 1024 * 1024 * 1024, // 5.2 GB
      total: 100 * 1024 * 1024 * 1024, // 100 GB
    },
    msg: "",
  }),

  sharesList: (): ApiResponse<
    Array<{
      id: string
      fileId: number
      fileName: string
      fileType: string
      password?: string
      createdAt: string
      expireTime?: string
    }>
  > => {
    const shares = []
    const shareCount = Math.floor(Math.random() * 5) + 3

    for (let i = 0; i < shareCount; i++) {
      const fileName = fileNames[Math.floor(Math.random() * fileNames.length)]
      const shareId = Math.random().toString(36).substring(7)
      const hasPassword = Math.random() > 0.5

      shares.push({
        id: shareId,
        fileId: Math.floor(Math.random() * 1000000),
        fileName,
        fileType: getMimeType(fileName),
        password: hasPassword ? Math.random().toString(36).substring(2, 6).toUpperCase() : undefined,
        createdAt: getRandomDate(),
        expireTime: Math.random() > 0.7 ? new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString() : undefined,
      })
    }

    return {
      code: 1,
      data: shares,
      msg: "",
    }
  },

  filePreview: (fileId: number): ApiResponse<{
    fileId: number
    fileName: string
    fileSize: number
    mimeType: string
    previewUrl: string
    downloadUrl: string
  }> => {
    const fileName = fileNames[Math.floor(Math.random() * fileNames.length)]
    const ext = fileName.split(".").pop()?.toLowerCase()

    // Generate mock preview URL based on file type
    let previewUrl = ""
    if (["jpg", "png", "gif"].includes(ext || "")) {
      previewUrl = `/placeholder.svg?height=600&width=800&query=preview+image`
    } else if (ext === "pdf") {
      previewUrl = "data:application/pdf;base64,mock-pdf-data"
    } else if (ext === "mp4") {
      previewUrl = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
    } else if (ext === "mp3") {
      previewUrl = "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
    }

    return {
      code: 1,
      data: {
        fileId,
        fileName,
        fileSize: getRandomSize(),
        mimeType: getMimeType(fileName),
        previewUrl,
        downloadUrl: `/api/files/${fileId}/download`,
      },
      msg: "",
    }
  },
}
